package com.zhuifeng.orders.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.zhuifeng.orders.mapper.StatementMapper;
import com.zhuifeng.orders.service.StatementService;
import com.zhuifeng.product.domain.Type;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @description:
 * @author: 周国强
 * @time: 2022/8/31 9:06
 */
@Service
public class StatementServiceImpl implements StatementService {
    private final StatementMapper statementMapper;
    private final Redisson redisson;
    private final StringRedisTemplate redisTemplate;
    private final static String INDEX_TYPE_ALL= "product_type_All";
    private final static String INDEX_LOCK= "product_type_All_Lock";

    public StatementServiceImpl(StatementMapper statementMapper, Redisson redisson, StringRedisTemplate redisTemplate) {
        this.statementMapper = statementMapper;
        this.redisson = redisson;
        this.redisTemplate = redisTemplate;
    }

    /**
     * 查询所有类型
     * @return
     */
    @Override
    public List<Type> selectTypeAll() {
        RLock lock = redisson.getLock(INDEX_LOCK);
        //从缓存中获取
        if (redisTemplate.hasKey(INDEX_TYPE_ALL)){
            return JSONObject.parseArray(redisTemplate.opsForValue().get(INDEX_TYPE_ALL),Type.class);
        }
        try {
            lock.tryLock(1, TimeUnit.SECONDS);
            if (!redisTemplate.hasKey(INDEX_TYPE_ALL)){
                //查询数据库
                List<Type> types = this.statementMapper.selectTypeAll();
                //加入缓存
                redisTemplate.opsForValue().set(INDEX_TYPE_ALL,JSONObject.toJSONString(types),30,TimeUnit.MINUTES);
            }
            return JSONObject.parseArray(redisTemplate.opsForValue().get(INDEX_TYPE_ALL),Type.class);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return this.selectTypeAll();
    }
}
